package com.xm;

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Author：xm
 * Project：interview
 * Date：2025/8/5  18:32
 */

/*
 * 加锁 this 时，表示用当前的对象进行加锁，每个对象对应了一把锁；
 * 加锁 xxx.class 时，表示用某个类（而非类实例）来加锁，它是应用程序级别的，是全局生效的
 * */
public class _01_SynchronizedBlock2 {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        // 执行两次 synchronized (this)，不会阻塞
        threadPool.execute(() -> {
            _01_SynchronizedBlock2 block = new _01_SynchronizedBlock2();
            block.thisMethod();
        });
        threadPool.execute(() -> {
            _01_SynchronizedBlock2 block2 = new _01_SynchronizedBlock2();
            block2.thisMethod();
        });

        // 同一个对象，会阻塞
        // _01_SynchronizedBlock2 block = new _01_SynchronizedBlock2();
        // threadPool.execute(() -> {
        //     block.thisMethod();
        // });
        // threadPool.execute(() -> {
        //     block.thisMethod();
        // });

        // 执行两次 synchronized (xxx.class)，会阻塞
        threadPool.execute(() -> {
            _01_SynchronizedBlock2 block3 = new _01_SynchronizedBlock2();
            block3.classMethod();
        });
        threadPool.execute(() -> {
            _01_SynchronizedBlock2 block4 = new _01_SynchronizedBlock2();
            block4.classMethod();
        });

        threadPool.shutdown();
    }

    public void thisMethod() {
        synchronized (this) {
            System.out.println("synchronized (this)加锁：" + LocalDateTime.now());
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void classMethod() {
        synchronized (_01_SynchronizedBlock2.class) {
            System.out.println("synchronized (xxx.class)加锁" + LocalDateTime.now());
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
